package main

import (
	"fmt"
	"net/http"
)

type Ctl interface {
	ServiceName() string
}

type IndexCtl struct{ w http.ResponseWriter }

func (this *IndexCtl) ServiceName() string {
	return "indexController"
}

// func(*ctl,req)
// this.index
func (this *IndexCtl) Index(req *http.Request) {
	this.w.Write([]byte("hello word"))
}
func (this *IndexCtl) User(req *http.Request) {
	this.w.Write([]byte("user"))
}

type UserCtl struct {
	IndexCtl
}

//函数签名是 当前的 ctl 用于接口的方式
// class IndeCtl
//       def web(self)
// this.Index
// Index(u)
//
func web(f func(ctl *IndexCtl, req *http.Request)) http.HandlerFunc {
	return func(w http.ResponseWriter, req *http.Request) {
		f(&IndexCtl{
			w: w,
		}, req)
	}
}

type Demo struct {
}

func (this *Demo) Get(username string) string {
	return username
}

//我们在http./handunfc
// wrier req
// ce func req weurier
// f&^dor wurier.req
// call_user_func 类似一样
// retunr hnahder
// weuter req
// &de
// func.get
// &demo.getcall.&demo,method
// &demo.get
// this.get get(&user."888)
//
func ce(f func(d *Demo, username string) string) http.HandlerFunc {
	return func(writer http.ResponseWriter, request *http.Request) {
		f(&Demo{}, request.RequestURI)
	}
}

type Stduent struct {
}

func (s Stduent) Index(username string) string {
	fmt.Println(username)
	return username
}
func main() {
	//这个只是签名的方式必须是 IndexCtl的方式
	//但是无法在接口进行实现 必须 传递指针的方式
	//函数只是 func 肯定可以为进行
	router := http.NewServeMux()
	router.HandleFunc("/", web((*IndexCtl).Index))
	router.HandleFunc("/user", web((*IndexCtl).User))
	http.ListenAndServe(":8080", router)
	//fmt.Printf("%T",(*Demo).Get)
	//ce((*Demo).Get)

	//router := http.NewServeMux()
	//router.HandleFunc("/",We((*O).Index))
	//http.ListenAndServe(":9091",router)
	//(*O).Index(&O{})
	// func(*main.Demo)
	//s := Stduent{}
	//(*Stduent).Index(&s, "222") //底层都是这样操作处理 指针和费指针方式
	//默认方法 这样的方式 可以看出 如果是 s 则直接拷贝的是传递的是 新的 studtct 非指针的值信息
	//其实在很多都是用的 比较多的方式 函数签名 接口签名
	//在java go rust 中比较常见 这种的方式 func () func
	// call-reeyturn wieyr req inde cor req weyir .index
	// func
	//这种的反函数
}

//就是 func c *ctx 上西瓦类似的
// func *O
// *().get
// f().
//
type O struct {
	w   http.ResponseWriter
	req *http.Request
}

func (this *O) Index() {
	this.w.Write([]byte(this.req.RequestURI))
}
func We(f func(o *O)) http.HandlerFunc {
	return func(w http.ResponseWriter, req *http.Request) {
		f(&O{w: w, req: req})
	}
}

//类似执行了 &demo.call()
// *main.Get
// f()
// &demo,参数
// call_user_func this,method args
// [this.call,args]
//这些都是在go经常使用的方式
//参数+栈+返回——调用+call_func-return
// hans 签名即可
// func(*
